package cn.jinbyte.starter.message.service;

import cn.jinbyte.core.exception.SysException;
import cn.jinbyte.starter.message.config.EmailProperties;
import cn.jinbyte.starter.message.model.EmailNoticeDTO;
import cn.jinbyte.starter.message.annotation.EmailNoticeLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * 自定义邮件服务
 *
 * @author jintingying
 * @since 1.0
 */
@Slf4j
public class EmailNoticeService {

    private final EmailProperties emailProperties;

    private final Properties props;

    public EmailNoticeService(EmailProperties emailProperties) {
        this.emailProperties = emailProperties;
        this.props = new Properties();
        this.props.put("mail.smtp.host", emailProperties.getHost());
        this.props.put("mail.smtp.auth", "true");
        this.props.put("mail.smtp.localhost", "127.0.0.1");
    }

    public boolean isDev() {
        return "dev".equals(emailProperties.getEnv());
    }

    @EmailNoticeLog
    public void send(EmailNoticeDTO notice) {
        String emails = Arrays.stream(StringUtils.split(notice.getTo(), ";"))
                .distinct()
                .collect(Collectors.joining(","));
        if (StringUtils.isBlank(emails)) {
            throw new SysException("邮件接收地址不能为空");
        }
        if (isDev()) {
            log.info("向 {} 发送邮件（标题：{}，内容：{}）", notice.getTo(), notice.getSubject(), notice.getContent());
            return;
        }

        // 构造mail session
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(emailProperties.getUsername(), emailProperties.getPassword());
            }
        });

        try {
            // 构造MimeMessage 并设定基本的值
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(emailProperties.getUsername()));
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(emails));
            msg.setSubject(MimeUtility.encodeText(notice.getSubject(), "UTF-8", "B"));
            // 构造Multipart
            Multipart mp = new MimeMultipart();
            // 添加正文
            MimeBodyPart mbpContent = new MimeBodyPart();
            mbpContent.setContent(notice.getContent(), "text/html;charset=gb2312");
            mp.addBodyPart(mbpContent);

            // 向Multipart添加附件
            for (String filename : notice.getAttachment()) {
                MimeBodyPart mbpFile = new MimeBodyPart();
                FileDataSource fds = new FileDataSource(filename);
                mbpFile.setDataHandler(new DataHandler(new FileDataSource(filename)));
                filename = new String(fds.getName().getBytes(), StandardCharsets.ISO_8859_1);
                mbpFile.setFileName(filename);
                mp.addBodyPart(mbpFile);
            }

            // 向Multipart添加MimeMessage
            msg.setContent(mp);
            msg.setSentDate(new Date());
            msg.saveChanges();

            // 发送邮件
            Transport transport = session.getTransport(emailProperties.getProtocol());
            transport.connect(emailProperties.getHost(), emailProperties.getUsername(), emailProperties.getPassword());
            transport.sendMessage(msg, msg.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new SysException("邮件发送失败");
        }
    }


}
